package com.huawei.utils;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

public class MyUtils {

	/**
	 * 数据类型转换：将request表单中的数据转换为实体类的属性值。【 要求：form表单的标签控件的name属性名需要和是类的属性名一致（区分大小写）】
	 * 
	 * @param request request请求对象
	 * @param clazz   实体类的Class
	 * @return 获取表单数据的实体类实例对象
	 */
	public static <T> T convertRequest2BeanWithFileUpload(HttpServletRequest request, Class<T> clazz) {
		// 返回值
		T t = null;

		// 给BeanUtils注册类型转换器
//		// 处理时间格式
//		DateConverter dateConverter = new DateConverter();
//		// 设置日期格式
//		dateConverter
//				.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss" });
		// 注册日期类型的转换器
		ConvertUtils.register(new BeanUtilsDateConverter(), Date.class);

		/***************************** 普通form表单的处理 ************************************/
		try {
			// 使用Class创建实体类的一个实例对象
			t = clazz.newInstance();
			// 从request中取出表单值，设置给实体类的同名属性
			if (request != null) {
				// 从request对象中获取所有的表单的name属性的值
				Enumeration<String> formTagNameValues = request.getParameterNames();
				// 遍历每个标签的name属性，使用反射进行赋值
				while (formTagNameValues.hasMoreElements()) {
					// 获取标签的name属性的值
					String tagNameValue = formTagNameValues.nextElement();
					// 使用标签的name属性的值获取该标签的控件的值
					String tagValue = request.getParameter(tagNameValue);
					// 使用BeanUtils进行实体类的属性的反射调用设置
					BeanUtils.setProperty(t, tagNameValue, tagValue);
				}
			}
		} catch (Exception e) {
			// 获取Class实例对象异常
			System.out.println("工具类convertRequest2BeanWithFileUpload方法中异常：");
			e.printStackTrace();
		}

		/*****************************
		 * 文件流form表单控件的处理
		 ************************************/
		try {
			//System.out.println("PPPPPP:::::" + request.getContentType());
			// 判断rquest中是否包含了文件流对象(ContentType中是否为 multipart/form-data )
			if (request.getContentType() != null && request.getContentType().split(";")[0].equals("multipart/form-data")) {
				// part是对应的form表单中的一个控件对象
				// request中将form表单中的一个控件对象封装到一个part中
				Collection<Part> parts = request.getParts();// 如果获取不到parts，注意检查servlet是否使用了@MultipartConfig注解

				// 获取当前服务器的绝对路径
				//System.out.println("request.getContextPath()::::" + request.getContextPath());
				
				//System.out.println("realpath::::" + request.getServletContext().getRealPath("/"));
				// 服务器发布的项目的存储的真实的物理路径
				// D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\servlet20190528\
				String strBaseRealPath = request.getServletContext().getRealPath("/");
				// 当前保存文件流对象的文件目录
				String strFileSavePath = "static/uploadFiles/userinfoFiles/";
				// 根据文件目录的物理地址创建该目录
				File tmpFile = new File(strBaseRealPath + strFileSavePath);
				// 判断文件目录是否存在，如果不存则创建该目录
				if (!tmpFile.exists()) {
					tmpFile.mkdirs();
				}

				// 文件前缀
				String strFilePrefix = "userInfoImg";

				// 遍历part集合，找出含有文件流的part进行文件上传处理
				if (parts != null && parts.size() > 0) {
					// 一次遍历每个part对象 即 每个form表单对象
					for (Part part : parts) {
						// 获取每个part的ContentType属性，如果是文件流对象，则ContentType属性不为null，含有具体的值
						// part.getSize() 获取的是文件流对象的内容的大小
						String partContentType = part.getContentType();
						// 当前的part是文件流对象，进行文件上传处理
						if (partContentType != null && !partContentType.equals("") && part.getSize() > 0) {
							
							// 获取包含文件后缀信息的上下文的字符描述串
//							String strContent = part.getHeader("Content-Disposition");
//							System.out.println("getHeader(\"Content-Disposition\")::::" + strContent);
//							System.out.println("-----类型名称------->" + part.getName());
//							System.out.println("-----类型------->" + part.getContentType());
//							System.out.println("-----提交的类型名称------->" + part.getSubmittedFileName());
							
							
							// 获取上传文件的文件后缀
							// 上传文件的原始名字
							String submitFileName = part.getSubmittedFileName();
							// 提出文件的后缀
							// 使用正则表达式提取文件的后缀类型
							// 提取后缀的正在表达式
							Pattern pattern = Pattern.compile("\\.\\w+$");
							// 现在创建 matcher 对象
							Matcher matcher = pattern.matcher(submitFileName);
							// 文件类型后缀:默认类型为 .dat
							String strFileType = ".dat";
							if (matcher.find()) {
								// 获取匹配结果
								strFileType = matcher.group();
							}

							// 生成新的文件名字：文件名字的格式根据业务需求而定
							// 此处文件名格式： 文件前缀时间毫秒数文件后缀
							String strNewFileName = strFilePrefix + System.currentTimeMillis() + strFileType;

							// 调用part的write方法，将文件流内容写到服务器指定的路径目录下
							// 保存rquest对象中的文件流到服务器指定目录下
							part.write(strBaseRealPath + strFileSavePath + strNewFileName);
							// 获取文件流对象的中的流内容（也就是文件的二进制流信息）
							// part.getInputStream();

							// 将文件保存在服务器的相对地址保存到实体类的对象的属性字段
							/*
							 * 因为避免file控件的neme属性值和实体类属性值一样，则会被自动赋值， 要求file控件类的name属性值采用如下格式：file_实体类属性名
							 */
							// 获取file控件的name属性值
							String strFilePropertityNameValue = part.getName();
							// 剔除前缀，获取与实体类对象的属性名
							String strP = strFilePropertityNameValue.replaceFirst("file_", "");
							BeanUtils.setProperty(t, strP, strFileSavePath + strNewFileName);
						}
					}
				}

			}
		} catch (Exception e) {
			// 文件上传处理异常
			System.out.println("文件上传处理异常:");
			e.printStackTrace();
		}

		return t;
	}

	/**
	 * 将日期类型转换为指定格式的字符串 注意：格式串的格式和日期字符串的格式要保持一致，否无法进行转换
	 * 
	 * @param strDate   被转化的日期字符串
	 * @param strFormat 日期字符串的格式
	 * @return 转换之后的日期对象
	 */
	public static Date convertString2Date(String strDate, String strFormat) {
		// 返回值（根据业务需求确定默认的返回值）
		// Date date = new Date();
		Date date = null;
		// 如果格式串为空，则使用默认格式串
		if (strFormat == null) {
			strFormat = "yyyy-MM-dd HH:mm:ss";
		}
		if (strDate != null && !strDate.equals("")) {
			// 创建日期格式化处理类的实例对象
			SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
			try {
				// 进行转换处理
				date = sdf.parse(strDate);
			} catch (ParseException e) {
				// 异常处理
				System.out.println("日期字符串转化为日期对象异常：" + e.getMessage());
			}
		}
		return date;

	}

	/**
	 * 将日期类型转换为指定格式的字符串
	 * 
	 * @param date      被转化的日期类型
	 * @param strFormat 日期字符串的格式
	 * @return 转换之后的日期格式串
	 */
	public static String convertDate2String(Date date, String strFormat) {

		// 返回值
		String strDate = null;

		if (date != null) {
			// 如果格式串为空，则使用默认格式串
			if (strFormat == null) {
				strFormat = "yyyy-MM-dd HH:mm:ss";
			}
			// 创建日期格式化处理类的实例对象
			SimpleDateFormat sdf = new SimpleDateFormat(strFormat);
			// 进行格式化处理
			strDate = sdf.format(date);
		}
		return strDate;
	}

	public static void main(String[] args) {
		String sttttt = "bg-001.jpg bg-001.jpg";
		// 正在表达式
		Pattern pattern = Pattern.compile("\\.\\w+$");
		// 现在创建 matcher 对象
		Matcher matcher = pattern.matcher(sttttt);
		System.out.println("正则表达式匹配的个数：" + matcher.groupCount());
		if (matcher.find()) {
			System.out.println("匹配结果：" + matcher.group());
		} else {
			System.out.println("M诶有");
		}
	}

}
